



const useAddEditHook = (
    initFormData = {},
    configOption = {},
    emit,
    props,
)=>{
    const { proxy } = getCurrentInstance();
    const allConfiOption = {
        moduleName: "模块名",
        primaryKey: "id",
        addApiFn: null,
        editApiFn: null,
        infoApiFn: null,
        beforeShowInfoFn: null, // 显示详情前执行函数
        beforeRequestFn: null, // 新增或修改求前执行函数,
        afterRequestFn: null, // 新增或修改请求后执行函数
        beforeCloseFn: null, // 关闭弹框前执行函数
        ...configOption,
    };

    const gFormLoading = ref(false); // 提交loading
    const gFormLoading2 = ref(false); // 暂存loading
    const gFormDisabled = ref(false); // 表单禁用(查看模式)
    const gFormData = ref(initFormData); // 表单数据
    let gInitFormData = {}; // 保存最初始表单数据
    const gVisible = ref(false); // 弹框是否显示

    const gFormTitle = computed(() => {
        const { moduleName, primaryKey } = allConfiOption;
        if (gFormDisabled.value) {
            return "查看" + moduleName;
        } else if (gFormData.value[primaryKey]) {
            return "编辑" + moduleName;
        } else {
            return "新增" + moduleName;
        }
    });

    // 创建之前
    onMounted(() => {
        // 保存表单赶紧的初始数据
        gInitFormData = JSON.stringify(gFormData.value);
    });

    /**
     * 查询详情
     * @param {*} data  行数据
     * @param {*} type  类型
     * @returns
     */
    const gShowDetail = (data, type = "edit") => {
        if(!data && ['edit','see'].includes(type)) return console.error('未传入行数据信息')
        // 判断
        if (!["edit", "see", "add"].includes(type)) {
            return proxy.$message.warning("传入type错误，支持see、add、edit");
        }
        if (type === "add") {
            gVisible.value = true;
            return;
        }
        if (type === "see") gFormDisabled.value = true;
        const { infoApiFn, primaryKey, beforeShowInfoFn, } = allConfiOption;
        if (!data[primaryKey]) {
            return proxy.$message.warning(
                `查找数据主键：${primaryKey}不存在，前端代码错误`
            );
        }
        /*  请求数据，这里提交data是为了增强，不一定查找只要交主键，提供给api函数自主取值 */
        infoApiFn(data)
            .then(async (res) => {
                let responeData = { ...res };
                // 打开执行钩子
                if (beforeShowInfoFn && typeof beforeShowInfoFn === "function") {
                    responeData = beforeShowInfoFn(res);
                    if (responeData === false) return;
                }
                // 很重要！！！ 也就是beforeShowInfo钩子返回的结果最终都会给表单。
                // 所以，如果外层需要剔除多余、或增加 某些字段，请在这个钩子里操作。
                gFormData.value = responeData;
                gVisible.value = true;
            })
            .catch((err) => {
                console.log("获取详情出错", err);
            });
    };

    /**
     * 表单提交数据(外部调用)
     * @param {boolean } isTempSave  是否暂存
     * @param {*} fieldInfo  暂存模式下至少要填写哪些字段
     */
    const gFormSubmit = async (isTempSave, fieldInfo = {}) => {
        if (isTempSave === true) {
            // 暂存提交
            for (const keyName of Object.keys(fieldInfo)) {
                if (!gFormData.value[keyName]) {
                    proxy.$message.warning(`暂存模式下，${keyName}字段不能为空`);
                    break;
                }
            }
            formSubmitFn(isTempSave);
        } else {
            // 正常提交
            proxy.$refs.gFormRef.validate(async (valid) => {
                if (!valid) return; //   验证不通过
                formSubmitFn();
            });
        }
    };


    /**
     * 真正的提交逻辑
     * @param {boolean} isTempSave
     */
    const formSubmitFn = async (isTempSave) => {
        // 拷贝数据
        let cloneData = JSON.parse(JSON.stringify(gFormData.value));
        // 解构
        const { addApiFn, editApiFn, primaryKey, beforeRequestFn, afterRequestFn } =
            allConfiOption;
        // 前置钩子
        if (beforeRequestFn && typeof beforeRequestFn === "function") {
            // 重要：这里返回值最终会作为表单的提交数据。所以外部可做额外添加。 false则跳出逻辑
            cloneData = await beforeRequestFn(cloneData);
            if (cloneData === false) return;
        }
        if (isTempSave === true) {
            gFormLoading2.value = true; // 暂存loading
        } else {
            gFormLoading.value = true; // 提交loading
        }
        // 承接返回数据
        let responseData = null;
        // 请求逻辑
        try {
            if (cloneData[primaryKey]) {
                responseData = await editApiFn(cloneData); // 修改
                proxy.$message.success("修改成功");
            } else {
                responseData = await addApiFn(cloneData); // 新增
                proxy.$message.success("新增成功");
            }
        } catch (error) {
            return console.error("新增或修改出错", error);
        } finally {
            if (isTempSave) {
                gFormLoading2.value = false;
            } else {
                gFormLoading.value = false;
            }
        }
        // 后置钩子
        if (afterRequestFn && typeof afterRequestFn === "function") {
            let result = await afterRequestFn(responseData); // 将修改后的数据交给外面
            if (result === false) return; // 如果返回false，则不执行后续逻辑
        }
        // 关闭弹框
        gFormCancel();
        // 刷新列表
        emit && emit("refreshList");
    };

    // 关闭弹框
    const gFormCancel = async () => {
        const { beforeCloseFn } = allConfiOption;

        // 移除校验
        if (proxy.$refs.gFormRef) {
            proxy.$refs.gFormRef.clearValidate();
        }
        // 表单重置(干净的数据还回来)
        gFormData.value = JSON.parse(gInitFormData);
        // 关闭禁用
        gFormDisabled.value = false;
        // 执行中间件，外部操作
        if (beforeCloseFn && typeof beforeCloseFn === "function") {
            await beforeCloseFn();
        }
        //关闭弹框
        gVisible.value = false;
    };

    return {
        gVisible,  // 控制弹框显示隐藏
        gFormLoading, // 提交的loading控制
        gFormLoading2, // 暂存的loading控制
        gFormDisabled,  // 表单禁用(查看模式)
        gFormData,  // 表单数据
        gFormTitle,  // 表单标题
        gShowDetail, // 详情方法(传入对象，包含主键名和对应值)
        gFormSubmit,  // 提交方法(传入true，代表暂存)
        gFormCancel,  // 关闭方法
    };

}

